Bazat e te dhenave relacionale
Nje baze te dhenash mban nje ose me shume tabela informacioni. Nje tabele eshte e perbere nga rreshta dhe kolona. Rreshtat ne nje tabele quhen rekorde, ndersa kolonat quhet fusha ose atribute. Nje databaze relacionale perbehet nga dy ose me shume tabela.
Per te kuptuar dobite e ndarjes se te dhenave ne disa tabela do te marrim nje shembull konkret. Supozojme qe jemi pergjegjes per regjistrimin e te gjitha librave qe dalin nga libraria. Per kete mund te perdorim nje tabele te vetme:
| Emri | Adresa | Celular | Libri | Data e kthimit |
|---|---|---|---|---|
| Alban Afmeti | Qyteti Studenti, Tirane | 0664064062 | "Advanced PHP" | 2017-05-01 |
Kjo tabele i ploteson nevojat baze per te regjistruar se cili person ke liber ka marre, por nuk eshte shume efikase, kerkon shume hapesire dhe kohe per t'u mirembajtur. Pse? Arsyeja e ketyre probleme qendron ne faktin qe p.sh. ne rast se lexuesi Alban Afmeti merr me shume libra pergjate kohes, ne duhet te shtojme informacionet e tij si Emri, Adresa, Celular per cdo liber te ri qe ai merr.
| Emri | Adresa | Celular | Libri | Data e kthimit |
|---|---|---|---|---|
| Alban Afmeti | Qyteti Studenti, Tirane | 0664064062 | "Advanced PHP" | 2017-05-01 |
| Drilon Kerxhaliu | Ali Demi, Tirane | 0662017293 | "Web Programming" | 2017-06-02 |
| Alban Afmeti | Qyteti Studenti, Tirane | 0664064062 | "PHP Performance" | 2017-05-12 |
| Brilant Afmeti | Rruga Kavajes, Tirane | 0662583993 | "Social Life" | 2017-06-12 |
| Alban Afmeti | Qyteti Studenti, Tirane | 0664064062 | "PHP Cookbook" | 2017-06-03 |
| Alban Afmeti | Qyteti Studenti, Tirane | 0664064062 | "Advanced SQL" | 2017-06-12 |
Duke rifutur informacionin e kontaktit per lexuesin Alban Afmeti eshte humbje kohe dhe rritet mundesia per te gabuar. Supozojme qe duhet te behet nje modifikim, te ndryshoet adresa e lexuesit Alban Afmeti. Qe te kemi adrese te sakte tek te gjitha rekordet, do te na duhet te gjejme dhe te modifikojme te gjitha rekordet me radhe, gje qe eshte humbje kohe dhe mund te na dergoje edhe drejt gabimeve gjate modifikimit. Perseritja e informacionit eshte problem edhe per hapesiren e memories. Per te shmangur keto probleme vjen ne ndihme ndarja e informacionit ne tabela te ndryshme. Cdo pjese informacioni duhet te ruhet vetem njehere ne menyre qe mos te kemi perseritje informacioni.
Ndajme tabelen e mesiperme ne dy tabela te vecanta:
Tabela
lexuesit
| Emri | Adresa | Celular |
|---|---|---|
| Alban Afmeti | Qyteti Studenti, Tirane | 0664064062 |
| Drilon Kerxhaliu | Ali Demi, Tirane | 0662017293 |
| Brilant Afmeti | Rruga Kavajes, Tirane | 0662583993 |
Tabela
librat
| Libri | Data e kthimit |
|---|---|
| "Advanced PHP" | 2017-05-01 |
| "Web Programming" | 2017-06-02 |
| "PHP Performance" | 2017-05-12 |
| "Social Life" | 2017-06-12 |
| "PHP Cookbook" | 2017-06-03 |
| "Advanced SQL" | 2017-06-12 |
Tani qe te dhenat jane ruajtur me efikasitet, na duhet nje menyre per te treguar se cilat rekorde ne tabelen lexuesit korrespondojne me cilat rekorde ne tabelen librat. Domethene duhet te dime se lexuesi ne tabelen lexuesit cfare libri ka marre ne tabelen librat.
Per te bere lidhjen midis tabelave duhet fillimisht te vendosim nga nje ID per secilin rekord ne tabelen lexuesit. Id-te duhet te jene unike ndermjet rekordeve.
| ID | Emri | Adresa | Celular |
|---|---|---|---|
| 1 | Alban Afmeti | Qyteti Studenti, Tirane | 0664064062 |
| 2 | Drilon Kerxhaliu | Ali Demi, Tirane | 0662017293 |
| 3 | Brilant Afmeti | Rruga Kavajes, Tirane | 0662583993 |
Po ashtu, shtojme nje kolone te re ne tabelen librat me emrin ID Lexues. Kjo kolone do te mbaje vleren e id-se se lexuesit qe e ka marre librin ne rekordin respektiv.
| Libri | Data e kthimit | ID Lexues |
|---|---|---|
| "Advanced PHP" | 2017-05-01 | 1 |
| "Web Programming" | 2017-06-02 | 2 |
| "PHP Performance" | 2017-05-12 | 1 |
| "Social Life" | 2017-06-12 | 3 |
| "PHP Cookbook" | 2017-06-03 | 1 |
| "Advanced SQL" | 2017-06-12 | 1 |
Ne kete rast e vetmja gje qe perseritet eshte ID-ja e lexuesit ne tabelen librat dhe nuk harxhohet hapesire si ne rastin e meparshem. Edhe ne rast se duam te bejme ndonje ndryshim te te dhenave te lexuesit, mjafton te shkojme dhe te modifikojme nje rekord te vetem ne tabelen lexuesit. Lidhja e tabelave te mesiperme me njera-tjetren quhet lidhje One-to-many qe do te thote nje rekord ne tabelen e pare eshte i lidhur me disa rekorde ne tabelen e dyte. Nje lexues mund te marre shume libra, por nje liber mund te merret vetem nja nje lexues.
Atributi ID duhet te jete unik per cdo rekord ne tabelen lexuesit ne menyre qe te mund te perdoret si identifikues. Ne kete rast atributi ID quhet PRIMARY KEY, e perkthyer celes primar. Nje PRIMARY KEY eshte gjithmone unik. Lind pyetja, ne tabelen librat a eshte atributi ID Lexues celes primar? Ne shohim qe kjo fushe permban vlera te duplikuara keshtuqe pergjigja eshte jo. Nese fusha ID Lexues do te ishte PRIMARY KEY atehere lexuesit do te lejoheshin te merrnin vetem nga nje liber ne menyre qe fusha ID Lexues te kishte vlera unike. Ne kete rast do te na formohej nje lidhje One-to-One, pra nje lexues mund te marre vetem nje liber dhe nje liber mund te merret vetem nga nje lexues.
Fusha ID Lexues quhet FOREIGN KEY. Kjo fushe ndihmon ne lidhjen e tabeles lexuesit me tabelen librat dhe konsiderohet celes i jashtem.
Cdo tabele ka nevoje per nje identifikues si PRIMARY KEY. Dukeqenese tabeles librat nuk i kemi vendosur nje PRIMARY KEY, le ta rindertojme me nje te tille:
| ID | Libri | Data e kthimit | ID Lexues |
|---|---|---|---|
| 1 | "Advanced PHP" | 2017-05-01 | 1 |
| 2 | "Web Programming" | 2017-06-02 | 2 |
| 3 | "PHP Performance" | 2017-05-12 | 1 |
| 4 | "Social Life" | 2017-06-12 | 3 |
| 5 | "PHP Cookbook" | 2017-06-03 | 1 |
| 6 | "Advanced SQL" | 2017-06-12 | 1 |
Ne jeten reale, ne librari nje liber nuk merret vetem nga nje lexues i vetem dhe me pas te mos vleje me. Pasi libri kthehet nga lexuesi i pare ate mund ta marre nje lexues tjeter. Ndaj eshte e nevojshme nje lloj tjeter lidhjeje te cilen do ta trajtojme me poshte.
Supozojme qe libri Advanced PHP pasi eshte kthyer nga lexuesi Alban Afmeti, te merret nga nje lexues tjeter p.sh. Drilon Kerxhaliu. Ne kete moment duhet te shtojme nje rekord te ri ne tabelen librat ku te regjistrojme librin qe u mor nga lexuesi Drilon Kerxhaliu:
| ID | Libri | Data e kthimit | ID Lexues |
|---|---|---|---|
| 1 | "Advanced PHP" | 2017-05-01 | 1 |
| 2 | "Web Programming" | 2017-06-02 | 2 |
| 3 | "PHP Performance" | 2017-05-12 | 1 |
| 4 | "Social Life" | 2017-06-12 | 3 |
| 5 | "PHP Cookbook" | 2017-06-03 | 1 |
| 6 | "Advanced SQL" | 2017-06-12 | 1 |
| 7 | "Advanced PHP" | 2017-08-14 | 2 |
Pasi shtuam rekordin e fundit, shohim qe kemi perseritje te dhenash. Libri Advanced PHP eshte perseritur dy here ne tabelen librat. Per te shmangur kete gje na duhet nje lidhje e re qe quhet Many-to-many, nje lexues mund te marre disa libra, dhe nje liber mund te merret nga disa lexues. Per te implementuar kete gje na duhen tre tabela. Tabela lexuesit qe do te mbaje vetem listen e lexuesve, tabela librat qe do te mbaje listen e librave por pa perseritje, dhe nje tabele e ndermjetme qe mund ta quajme lexues_liber e cila ben lidhjen ndermjet lexuesit dhe librit, cili lexues ka marre cilin liber.
Tabela
lexuesit
| ID | Emri | Adresa | Celular |
|---|---|---|---|
| 1 | Alban Afmeti | Qyteti Studenti, Tirane | 0664064062 |
| 2 | Drilon Kerxhaliu | Ali Demi, Tirane | 0662017293 |
| 3 | Brilant Afmeti | Rruga Kavajes, Tirane | 0662583993 |
Tabela
lexues_liber
| ID | ID Lexues | ID Liber | Data e kthimit |
|---|---|---|---|
| 1 | 1 | 1 | 2017-05-01 |
| 2 | 2 | 2 | 2017-06-02 |
| 3 | 1 | 3 | 2017-05-12 |
| 4 | 3 | 4 | 2017-06-12 |
| 5 | 1 | 5 | 2017-06-03 |
| 6 | 1 | 6 | 2017-06-12 |
| 7 | 2 | 1 | 2017-08-14 |
Tabela
librat
| ID | Libri | Autori |
|---|---|---|
| 1 | "Advanced PHP" | O'Reilly |
| 2 | "Web Programming" | Robin Nixon |
| 3 | "PHP Performance" | O'Reilly |
| 4 | "Social Life" | Amy Cuddy |
| 5 | "PHP Cookbook" | Larry E. Ullman |
| 6 | "Advanced SQL" | Ray Harris |
Tabela lexues_liber mban fushen ID Lexues dhe ID Liber (te dyja fushat jane FOREIGN KEY) dhe percakton se cili lexues ka marre cilin liber. Ne kete menyre nuk kemi perseritje te dhenash pasi e vetmja gje qe perseritet eshte ID-ja e librit dhe ID-ja e lexuesit. Ne kete tabele kemi vendosur edhe nje PRIMARY KEY per cdo rekord qe eshte unik. Ne rastin e mesiperm eshte e lejueshme qe nje lexues te marre te njejtin liber perseri p.sh.:
| ID | ID Lexues | ID Liber | Data e kthimit |
|---|---|---|---|
| 20 | 1 | 1 | 2017-05-01 |
| 21 | 1 | 1 | 2017-08-12 |
Shohim qe rekordi me ID Lexues = 1 dhe ID Liber = 2 perseritet dy here, pra eshte e lejueshme qe nje lexues te marre te njejtin liber perseri. Ne rast se nuk duam te lejojme dicka te tille, dhe perseritjen 1:1 ta bejme unike (dmth. nje lexues qe e ka marre njehere me pare nje liber, te mos lejohet qe ta marre perseri), ndertojme nje PRIMARY KEY te dyfishte:
| ID Lexues | ID Liber | Data e kthimit |
|---|---|---|
| 1 | 1 | 2017-05-01 |
Kemi hequr fushen ID te vendosur me perpara, dhe kemi ndertuar nje PRIMARY KEY te dyfishte me ID Lexues dhe ID Liber. Ne kete rast perseritja 1:1 ne rekordin e dyte nuk lejohet. Nuk lejohet asnje rekord te perseritet nqs. e kane te njejte edhe ID Lexues edhe ID Liber.